package com.blackandwhitesensation.sice.dataaccess.dao;

import com.blackandwhitesensation.sice.dataaccess.entityManager.EntityManagerHelper;
import com.blackandwhitesensation.sice.modelo.Usuario;
import com.blackandwhitesensation.sice.modelo.UsuarioSistema;

import java.math.BigDecimal;
import java.math.BigInteger;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import javax.persistence.EntityManager;
import javax.persistence.Query;


/**
 * A data access object (DAO) providing persistence and search support for
 * Usuario entities. Transaction control of the save(), update() and delete()
 * operations must be handled externally by senders of these methods or must be
 * manually added to each of these methods for data to be persisted to the JPA
 * datastore.
 *
 * @author Zathura Code Generator http://code.google.com/p/zathura/
 * @see lidis.Usuario
 *
 */
public class UsuarioDAO implements IUsuarioDAO {
	private EntityManager getEntityManager() {
		return EntityManagerHelper.getEntityManager();
	}

	/**
	 * Perform an initial save of a previously unsaved Usuario entity. All
	 * subsequent persist actions of this entity should use the #update()
	 * method. This operation must be performed within the a database
	 * transaction context for the entity's data to be permanently saved to the
	 * persistence store, i.e., database. This method uses the
	 * {@link javax.persistence.EntityManager#persist(Object) EntityManager#persist}
	 * operation.
	 *
	 * <pre>
	 * EntityManagerHelper.beginTransaction();
	 * UsuarioDAO.save(entity);
	 * EntityManagerHelper.commit();
	 * </pre>
	 *
	 * @param entity
	 *            Usuario entity to persist
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void save(Usuario entity) {
		EntityManagerHelper.log("saving Usuario instance", Level.INFO, null);

		try {
			getEntityManager().persist(entity);
			EntityManagerHelper.log("save successful", Level.INFO, null);
		} catch (RuntimeException re) {
			EntityManagerHelper.log("save failed", Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Delete a persistent Usuario entity. This operation must be performed
	 * within the a database transaction context for the entity's data to be
	 * permanently deleted from the persistence store, i.e., database. This
	 * method uses the
	 * {@link javax.persistence.EntityManager#remove(Object) EntityManager#delete}
	 * operation.
	 *
	 * <pre>
	 * EntityManagerHelper.beginTransaction();
	 * UsuarioDAO.delete(entity);
	 * EntityManagerHelper.commit();
	 * entity = null;
	 * </pre>
	 *
	 * @param entity
	 *            Usuario entity to delete
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	public void delete(Usuario entity) {
		EntityManagerHelper.log("deleting Usuario instance", Level.INFO, null);

		try {
			entity = getEntityManager()
					.getReference(Usuario.class, entity.getAlias());
			getEntityManager().remove(entity);
			EntityManagerHelper.log("delete successful", Level.INFO, null);
		} catch (RuntimeException re) {
			EntityManagerHelper.log("delete failed", Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Persist a previously saved Usuario entity and return it or a copy of it
	 * to the sender. A copy of the Usuario entity parameter is returned when
	 * the JPA persistence mechanism has not previously been tracking the
	 * updated entity. This operation must be performed within the a database
	 * transaction context for the entity's data to be permanently saved to the
	 * persistence store, i.e., database. This method uses the
	 * {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
	 * operation.
	 *
	 * <pre>
	 * EntityManagerHelper.beginTransaction();
	 * entity = UsuarioDAO.update(entity);
	 * EntityManagerHelper.commit();
	 * </pre>
	 *
	 * @param entity
	 *            Usuario entity to update
	 * @return Usuario the persisted Usuario entity instance, may not be the
	 *         same
	 * @throws RuntimeException
	 *             if the operation fails
	 */
	public Usuario update(Usuario entity) {
		EntityManagerHelper.log("updating Usuario instance", Level.INFO, null);

		try {
			Usuario result = getEntityManager().merge(entity);
			EntityManagerHelper.log("update successful", Level.INFO, null);

			return result;
		} catch (RuntimeException re) {
			EntityManagerHelper.log("update failed", Level.SEVERE, re);
			throw re;
		}
	}

	public Usuario findById(String id) {
		EntityManagerHelper.log("finding Usuario instance with id: " + id,
				Level.INFO, null);

		try {
			Usuario instance = getEntityManager().find(Usuario.class, id);

			return instance;
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find failed", Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Find all  Usuario entities with a specific property value.
	 *
	 * @param propertyName
	 *            the metaData.name of the  Usuario property to query
	 * @param value
	 *            the property value to match
	 * @return List< Usuario> found by query
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> findByProperty(String propertyName, final Object value) {
		EntityManagerHelper.log("finding  Usuario instance with property: " +
				propertyName + ", value: " + value, Level.INFO, null);

		try {
			final String queryString = "select model from  Usuario model where model." +
					propertyName + "= :propertyValue";
			Query query = getEntityManager().createQuery(queryString);
			query.setParameter("propertyValue", value);

			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find by property metaData.name failed",
					Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * Find all Usuario entities with a specific property value.
	 *
	 * @param propertyName
	 *            the name of the Usuario property to query
	 * @param value
	 *            the property value to match
	 * @param rowStartIdxAndCount
	 *            Optional int varargs. rowStartIdxAndCount[0] specifies the the
	 *            row index in the query result-set to begin collecting the
	 *            results. rowStartIdxAndCount[1] specifies the the maximum
	 *            number of results to return.
	 * @return List<Usuario> found by query
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> findByProperty(String propertyName,
			final Object value, final int... rowStartIdxAndCount) {
		EntityManagerHelper.log("finding Usuario instance with property: " +
				propertyName + ", value: " + value, Level.INFO, null);

		try {
			final String queryString = "select model from Usuario model where model." +
					propertyName + "= :propertyValue";
			Query query = getEntityManager().createQuery(queryString);
			query.setParameter("propertyValue", value);

			if ((rowStartIdxAndCount != null) &&
					(rowStartIdxAndCount.length > 0)) {
				int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);

				if (rowStartIdx > 0) {
					query.setFirstResult(rowStartIdx);
				}

				if (rowStartIdxAndCount.length > 1) {
					int rowCount = Math.max(0, rowStartIdxAndCount[1]);

					if (rowCount > 0) {
						query.setMaxResults(rowCount);
					}
				}
			}

			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find by property name failed",
					Level.SEVERE, re);
			throw re;
		}
	}

	public List<Usuario> findByAlias(Object alias, int... rowStartIdxAndCount) {
		return findByProperty(ALIAS, alias, rowStartIdxAndCount);
	}

	public List<Usuario> findByAlias(Object alias) {
		return findByProperty(ALIAS, alias);
	}

	public List<Usuario> findByApellido(Object apellido,
			int... rowStartIdxAndCount) {
		return findByProperty(APELLIDO, apellido, rowStartIdxAndCount);
	}

	public List<Usuario> findByApellido(Object apellido) {
		return findByProperty(APELLIDO, apellido);
	}

	public List<Usuario> findByArtistasVerEnvivo(Object artistasVerEnvivo,
			int... rowStartIdxAndCount) {
		return findByProperty(ARTISTASVERENVIVO, artistasVerEnvivo,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByArtistasVerEnvivo(Object artistasVerEnvivo) {
		return findByProperty(ARTISTASVERENVIVO, artistasVerEnvivo);
	}

	public List<Usuario> findByCelular(Object celular,
			int... rowStartIdxAndCount) {
		return findByProperty(CELULAR, celular, rowStartIdxAndCount);
	}

	public List<Usuario> findByCelular(Object celular) {
		return findByProperty(CELULAR, celular);
	}

	public List<Usuario> findByCiudadResidencia(Object ciudadResidencia,
			int... rowStartIdxAndCount) {
		return findByProperty(CIUDADRESIDENCIA, ciudadResidencia,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByCiudadResidencia(Object ciudadResidencia) {
		return findByProperty(CIUDADRESIDENCIA, ciudadResidencia);
	}

	public List<Usuario> findByConocimientoMembresia(
			Object conocimientoMembresia, int... rowStartIdxAndCount) {
		return findByProperty(CONOCIMIENTOMEMBRESIA, conocimientoMembresia,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByConocimientoMembresia(
			Object conocimientoMembresia) {
		return findByProperty(CONOCIMIENTOMEMBRESIA, conocimientoMembresia);
	}

	public List<Usuario> findByCorreoElectronico(Object correoElectronico,
			int... rowStartIdxAndCount) {
		return findByProperty(CORREOELECTRONICO, correoElectronico,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByCorreoElectronico(Object correoElectronico) {
		return findByProperty(CORREOELECTRONICO, correoElectronico);
	}

	public List<Usuario> findByDeportePreferido(Object deportePreferido,
			int... rowStartIdxAndCount) {
		return findByProperty(DEPORTEPREFERIDO, deportePreferido,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByDeportePreferido(Object deportePreferido) {
		return findByProperty(DEPORTEPREFERIDO, deportePreferido);
	}

	public List<Usuario> findByDireccionResidencia(Object direccionResidencia,
			int... rowStartIdxAndCount) {
		return findByProperty(DIRECCIONRESIDENCIA, direccionResidencia,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByDireccionResidencia(Object direccionResidencia) {
		return findByProperty(DIRECCIONRESIDENCIA, direccionResidencia);
	}

	public List<Usuario> findByDireccionTrabaja(Object direccionTrabaja,
			int... rowStartIdxAndCount) {
		return findByProperty(DIRECCIONTRABAJA, direccionTrabaja,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByDireccionTrabaja(Object direccionTrabaja) {
		return findByProperty(DIRECCIONTRABAJA, direccionTrabaja);
	}

	public List<Usuario> findByEdad(Object edad, int... rowStartIdxAndCount) {
		return findByProperty(EDAD, edad, rowStartIdxAndCount);
	}

	public List<Usuario> findByEdad(Object edad) {
		return findByProperty(EDAD, edad);
	}

	public List<Usuario> findByEmpresaTrabaja(Object empresaTrabaja,
			int... rowStartIdxAndCount) {
		return findByProperty(EMPRESATRABAJA, empresaTrabaja,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByEmpresaTrabaja(Object empresaTrabaja) {
		return findByProperty(EMPRESATRABAJA, empresaTrabaja);
	}

	public List<Usuario> findByEstadoCivil(Object estadoCivil,
			int... rowStartIdxAndCount) {
		return findByProperty(ESTADOCIVIL, estadoCivil, rowStartIdxAndCount);
	}

	public List<Usuario> findByEstadoCivil(Object estadoCivil) {
		return findByProperty(ESTADOCIVIL, estadoCivil);
	}

	public List<Usuario> findByFechaNacimiento(Object fechaNacimiento,
			int... rowStartIdxAndCount) {
		return findByProperty(FECHANACIMIENTO, fechaNacimiento,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByFechaNacimiento(Object fechaNacimiento) {
		return findByProperty(FECHANACIMIENTO, fechaNacimiento);
	}

	public List<Usuario> findByLugarNacimiento(Object lugarNacimiento,
			int... rowStartIdxAndCount) {
		return findByProperty(LUGARNACIMIENTO, lugarNacimiento,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByLugarNacimiento(Object lugarNacimiento) {
		return findByProperty(LUGARNACIMIENTO, lugarNacimiento);
	}

	public List<Usuario> findByMusicaPreferida(Object musicaPreferida,
			int... rowStartIdxAndCount) {
		return findByProperty(MUSICAPREFERIDA, musicaPreferida,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByMusicaPreferida(Object musicaPreferida) {
		return findByProperty(MUSICAPREFERIDA, musicaPreferida);
	}

	public List<Usuario> findByNivelEducativo(Object nivelEducativo,
			int... rowStartIdxAndCount) {
		return findByProperty(NIVELEDUCATIVO, nivelEducativo,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByNivelEducativo(Object nivelEducativo) {
		return findByProperty(NIVELEDUCATIVO, nivelEducativo);
	}

	public List<Usuario> findByNombre(Object nombre, int... rowStartIdxAndCount) {
		return findByProperty(NOMBRE, nombre, rowStartIdxAndCount);
	}

	public List<Usuario> findByNombre(Object nombre) {
		return findByProperty(NOMBRE, nombre);
	}

	public List<Usuario> findByPaginasWebVisitadas(Object paginasWebVisitadas,
			int... rowStartIdxAndCount) {
		return findByProperty(PAGINASWEBVISITADAS, paginasWebVisitadas,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByPaginasWebVisitadas(Object paginasWebVisitadas) {
		return findByProperty(PAGINASWEBVISITADAS, paginasWebVisitadas);
	}

	public List<Usuario> findByPin(Object pin, int... rowStartIdxAndCount) {
		return findByProperty(PIN, pin, rowStartIdxAndCount);
	}

	public List<Usuario> findByPin(Object pin) {
		return findByProperty(PIN, pin);
	}

	public List<Usuario> findByProfesion(Object profesion,
			int... rowStartIdxAndCount) {
		return findByProperty(PROFESION, profesion, rowStartIdxAndCount);
	}

	public List<Usuario> findByProfesion(Object profesion) {
		return findByProperty(PROFESION, profesion);
	}

	public List<Usuario> findByRevistasLee(Object revistasLee,
			int... rowStartIdxAndCount) {
		return findByProperty(REVISTASLEE, revistasLee, rowStartIdxAndCount);
	}

	public List<Usuario> findByRevistasLee(Object revistasLee) {
		return findByProperty(REVISTASLEE, revistasLee);
	}

	public List<Usuario> findBySexo(Object sexo, int... rowStartIdxAndCount) {
		return findByProperty(SEXO, sexo, rowStartIdxAndCount);
	}

	public List<Usuario> findBySexo(Object sexo) {
		return findByProperty(SEXO, sexo);
	}

	public List<Usuario> findByTelefonoOficina(Object telefonoOficina,
			int... rowStartIdxAndCount) {
		return findByProperty(TELEFONOOFICINA, telefonoOficina,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByTelefonoOficina(Object telefonoOficina) {
		return findByProperty(TELEFONOOFICINA, telefonoOficina);
	}

	public List<Usuario> findByTelefonoResidencia(Object telefonoResidencia,
			int... rowStartIdxAndCount) {
		return findByProperty(TELEFONORESIDENCIA, telefonoResidencia,
				rowStartIdxAndCount);
	}

	public List<Usuario> findByTelefonoResidencia(Object telefonoResidencia) {
		return findByProperty(TELEFONORESIDENCIA, telefonoResidencia);
	}

	/**
	 * Find all Usuario entities.
	 *
	 * @param rowStartIdxAndCount
	 *            Optional int varargs. rowStartIdxAndCount[0] specifies the the
	 *            row index in the query result-set to begin collecting the
	 *            results. rowStartIdxAndCount[1] specifies the the maximum
	 *            count of results to return.
	 * @return List<Usuario> all Usuario entities
	 */
	 @SuppressWarnings("unchecked")
	public List<Usuario> findAll(final int... rowStartIdxAndCount) {
		EntityManagerHelper.log("finding all Usuario instances", Level.INFO,
				null);

		try {
			final String queryString = "select model from Usuario model";
			Query query = getEntityManager().createQuery(queryString);

			if ((rowStartIdxAndCount != null) &&
					(rowStartIdxAndCount.length > 0)) {
				int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);

				if (rowStartIdx > 0) {
					query.setFirstResult(rowStartIdx);
				}

				if (rowStartIdxAndCount.length > 1) {
					int rowCount = Math.max(0, rowStartIdxAndCount[1]);

					if (rowCount > 0) {
						query.setMaxResults(rowCount);
					}
				}
			}

			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find all failed", Level.SEVERE, re);
			throw re;
		}
	 }

	 public List<Usuario> findByCriteria(String whereCondition) {
		 EntityManagerHelper.log("finding Usuario " + whereCondition,
				 Level.INFO, null);

		 try {
			 String where = ((whereCondition == null) ||
					 (whereCondition.length() == 0)) ? "" : ("where " +
							 whereCondition);
			 final String queryString = "select model from Usuario model " +
					 where;
			 Query query = getEntityManager().createQuery(queryString);
			 List<Usuario> entitiesList = query.getResultList();

			 return entitiesList;
		 } catch (RuntimeException re) {
			 EntityManagerHelper.log("find By Criteria in Usuario failed",
					 Level.SEVERE, re);
			 throw re;
		 }
	 }

	 public List<Usuario> findPageUsuario(String sortColumnName,
			 boolean sortAscending, int startRow, int maxResults) {
		 EntityManagerHelper.log("finding Usuario findPageUsuario", Level.INFO,
				 null);

		 if ((sortColumnName != null) && (sortColumnName.length() > 0)) {
			 try {
				 String queryString = "select model from Usuario model order by model." +
						 sortColumnName + " " + (sortAscending ? "asc" : "desc");

				 return getEntityManager().createQuery(queryString)
						 .setFirstResult(startRow).setMaxResults(maxResults)
						 .getResultList();
			 } catch (RuntimeException re) {
				 throw re;
			 }
		 } else {
			 try {
				 String queryString = "select model from Usuario model";

				 return getEntityManager().createQuery(queryString)
						 .setFirstResult(startRow).setMaxResults(maxResults)
						 .getResultList();
			 } catch (RuntimeException re) {
				 throw re;
			 }
		 }
	 }

	 @SuppressWarnings("unchecked")
	 public Long findTotalNumberUsuario() {
		 EntityManagerHelper.log("finding Usuario count", Level.INFO, null);

		 try {
			 String queryString = "select count(*) from Usuario model";

			 return (Long) getEntityManager().createQuery(queryString)
					 .getSingleResult();
		 } catch (RuntimeException re) {
			 throw re;
		 }
	 }

	@Override
	public Long getSequence() throws Exception {
		
		try{
			String queryString  = "select nextval ('sequence_usuario')";
			Query query =getEntityManager().createNativeQuery(queryString);
			BigInteger salidaSecuencia = (BigInteger)query.getSingleResult();
			return salidaSecuencia.longValue();
			
		}catch(Exception e){
			throw e;
		}
		
	}
	 
	
}
